package com.tudou.annotations;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.util.ReflectionUtils;


public class AnnotationBeanPostProcessor extends PropertyPlaceholderConfigurer
		implements BeanPostProcessor, InitializingBean {

	private java.util.Properties pros;

	@SuppressWarnings("unchecked")
	private Class[] enableClassList = { String.class };

	@SuppressWarnings("unchecked")
	public void setEnableClassList(Class[] enableClassList) {
		this.enableClassList = enableClassList;
	}

	
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {

		Field[] fields = bean.getClass().getDeclaredFields();

		for (Field field : fields) {
			if (field.isAnnotationPresent(Properties.class)) {
				if (filterType(field.getType().toString())) {
					Properties p = field.getAnnotation(Properties.class);
					try {
						ReflectionUtils.makeAccessible(field);
						field.set(bean, pros.getProperty(p.name()));
					} catch (Exception e) {
						logger.error("tudou Annotation set field error!", e);
					}
				}
			}
		}

		return bean;
	}

	@SuppressWarnings("unchecked")
	private boolean filterType(String type) {
		if (type == null)
			return true;

		for (Class c : enableClassList) {
			if (c.toString().equals(type)) {
				return true;
			}
		}

		return false;
	}

	public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
		Method[] methods = bean.getClass().getDeclaredMethods();

		for (Method method : methods) {
			if (method.isAnnotationPresent(InitMethod.class)) {
				try {
					ReflectionUtils.makeAccessible(method);
					method.invoke(bean);
				} catch (Exception e) {
					logger.error("tudou Annotation set field error!", e);
				}
			}
		}

		return bean;
	}

	public void afterPropertiesSet() throws Exception {
		pros = mergeProperties();
	}
}